// HSS.Forms.DataListItem.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       DataListItem.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.Forms
{
	#region Using Directives
	using System;
	using System.Drawing;
	using System.Windows.Forms;
	using HSS.Data;

	#endregion

	#region DataListItem
	/// <summary>
	/// dataListItems are specialized ListViewItems that stores the associated data that makes up that item.
	/// </summary>
	public class DataListItem : ListViewItem, IUIDataElement, ICanBeDirty
	{
		#region Events
		/// <summary>
		/// Dirty Event
		/// </summary>
		public event EventHandler<DirtyEventArgs> DirtyChanged;
		/// <summary>
		/// InvokeDirty Event on Clients
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void InvokeDirty(object sender, DirtyEventArgs e)
		{
			if (null != this.DirtyChanged)
			{
				System.Delegate[] dlgs = this.DirtyChanged.GetInvocationList();
				if (null != dlgs)
				{
					foreach (Delegate d in dlgs)
					{
						if (null != d)
						{
							InvokeDelegate(d, new object[2] { sender, e });
						}
					}
				}
			}
		}
		/// <summary>
		/// Properly invokes a delegate allowing for a WinForm thread
		/// </summary>
		/// <param name="del">The delegate to call</param>
		/// <param name="args">Any arguments to be passed</param>
		public static void InvokeDelegate(Delegate del, object[] args)
		{
			System.ComponentModel.ISynchronizeInvoke synchronizer;
			synchronizer = del.Target as System.ComponentModel.ISynchronizeInvoke;
			if (synchronizer != null) //A Windows Forms object
			{
				if (synchronizer.InvokeRequired == false)
				{
					del.DynamicInvoke(args);
					return;
				}
				try
				{
					synchronizer.Invoke(del, args);
				}
				catch
				{ }
			}
			else //Not a Windows Forms object
			{
				del.DynamicInvoke(args);
			}
		}
		#endregion

		#region Constructor
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="data">The data for this DataListItem</param>
		public DataListItem(IDataContainer data)
			: base(data.Name)
		{
			this._data = data;
			this.ImageIndex = -1;
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="data">The data for this DataListItem</param>
		/// <param name="text">The displayed name for this DataListItem</param>
		/// <param name="imageIndex">The image index for this DataListItem</param>
		public DataListItem(IDataContainer data, string text, int imageIndex)
			: base(text, imageIndex)
		{
			this._data = data;
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="data">The data for this DataListItem</param>
		/// <param name="text">The displayed name for this DataListItem</param>
		/// <param name="imageKey">The image Key (name) for this DataListItem</param>
		public DataListItem(IDataContainer data, string text, string imageKey)
			: base(text, imageKey)
		{
			this._data = data;
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="text">The displayed name for this DataListItem</param>
		/// <param name="imageIndex">The image index for this DataListItem</param>
		public DataListItem(string text, int imageIndex)
			: base(text, imageIndex)
		{
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="text">The displayed name for this DataListItem</param>
		/// <param name="imageKey">The image Key (name) for this DataListItem</param>
		public DataListItem(string text, string imageKey)
			: base(text, imageKey)
		{
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="data">The data for this DataListItem</param>
		/// <param name="imageIndex">The image index for this DataListItem</param>
		public DataListItem(IDataContainer data, int imageIndex)
			: base(data.Name, imageIndex)
		{
			this._data = data;
		}
		/// <summary>
		/// ctor
		/// </summary>
		/// <param name="data">The data for this DataListItem</param>
		/// <param name="imageKey">The image Key (name) for this DataListItem</param>
		public DataListItem(IDataContainer data, string imageKey)
			: base(data.Name, imageKey)
		{
			this._data = data;
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the data that is the source for this item (Row)
		/// </summary>
		public IDataContainer Data
		{
			get { return _data; }
			set { _data = value; }
		} IDataContainer _data;
		/// <summary>
		/// Gets the type name of the type of data
		/// </summary>
		public string DataTypeName
		{
			get
			{
				if (null == _data)
					return string.Empty;
				return _data.GetType().AssemblyQualifiedName;
			}
		}
		/// <summary>
		/// Gets the Type of data
		/// </summary>
		public Type DataType
		{
			get
			{
				if (null == _data)
					return null;
				return _data.GetType();
			}
		}
		/// <summary>
		/// Indicates if the data has been modified
		/// </summary>
		public bool IsDirty
		{
			get { return _isDirty; }
			set
			{
				_isDirty = value;
				InvokeDirty(this, new DirtyEventArgs(value));
			}
		} bool _isDirty;
		#endregion

		#region Methods
		internal void Edit(DataListView View)
		{
			string title = ("Edit " + this.Data.Name);
			string currentId = this.Data.Id;
			DetailModuleContainer dmc = (DetailModuleContainer)Activator.CreateInstance(View.EditorForm);
			DetailModuleContainer.Saved += new EventHandler<DetailDataSavedEventArgs>(DetailModuleContainer_Saved);
			DetailModuleContainer.LoadInstance(dmc, View.EditorControl, title, this.Data, ModuleActions.Edit, true, View.FindForm());
			DetailModuleContainer.Saved -= new EventHandler<DetailDataSavedEventArgs>(DetailModuleContainer_Saved);
			if (this.IsDirty)
			{
				string newId = this.Data.Id;
				if (newId != currentId)
				{
					View.dataSource.Remove(currentId);
					View.dataSource.Add(newId, this.Data);
				}
				else
				{
					View.dataSource[this.Data.Id] = this.Data;
				}
				using (Graphics g = View.CreateGraphics())
				{
					g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
					g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
					View.BuildItem(g, this.Data, this);
				}
				View.SetColumnsWidth();
				View.IsDirty = true;
			}
		}
		#endregion

		#region Event Handlers
		void DetailModuleContainer_Saved(object sender, DetailDataSavedEventArgs e)
		{
			this.IsDirty = true;
			this.Data = e.SavedData;
		}
		#endregion
	}

	#endregion
}